<!DOCTYPE html>
<html lang="en">
<head>
	<meta charset="UTF-8">
	<title>Title</title>
</head>
<body>

</body>
<script>
	function customNew(fn, ...args){
		if (typeof fn !== 'function'){
			throw new TypeError('fn 需要是函数')
		}
		let obj = Object.create(fn.prototype)
		let result = fn.apply(obj, args)
		return result !== null && (typeof result === 'object' || typeof result === 'function') ? result : obj
	}
	// 测试 1：构造函数无返回值（应返回新对象）
function Person(name) {
    this.name = name;
}
const person = customNew(Person, "Alice");
console.log(person instanceof Person);   // 应输出 true
console.log(person.name);                // 应输出 "Alice"

// 对比原生 new
const nativePerson = new Person("Bob");
console.log(person.constructor === nativePerson.constructor); // 应输出 true

	// 测试 2：构造函数返回对象（优先使用返回值）
function Car() {
    return { type: "Tesla" };
}
const car = customNew(Car);
console.log(car.type);                  // 应输出 "Tesla"
console.log(car instanceof Car);        // 应输出 false（返回对象覆盖原型链）

// 测试 3：构造函数返回函数（特殊对象类型）
function Func() {
    return function() {};
}
const func = customNew(Func);
console.log(typeof func);               // 应输出 "function"

	// 测试 4：构造函数返回原始值（忽略返回值，返回新对象）
function NumberReturn() {
    return 42;
}
const numObj = customNew(NumberReturn);
console.log(numObj instanceof NumberReturn);  // 应输出 true
console.log(numObj.constructor === NumberReturn); // 应输出 true

	// 测试 5：传入非函数构造函数（应抛错）
try {
    customNew("not_a_function");
} catch (e) {
    console.log(e.message);  // 应输出 "fn 需要是函数"
}

// 测试 6：验证原型链正确性
function Animal() {}
const animal = customNew(Animal);
console.log(Object.getPrototypeOf(animal) === Animal.prototype); // 应输出 true

	// 测试 7：验证参数正确传递
function Sum(a, b) {
    this.result = a + b;
}
const sum = customNew(Sum, 3, 4);
console.log(sum.result);  // 应输出 7


</script>
</html>